package net.obxlabs.tweetpad.behaviour;

import net.nexttext.*;
import net.nexttext.behaviour.*;
import net.nexttext.behaviour.Action.ActionResult;
import net.nexttext.behaviour.standard.*;
import net.nexttext.property.BooleanProperty;
import net.nexttext.property.NumberProperty;
import net.nexttext.property.Vector3Property;
import penner.easing.*;

public class EaseIntoPlay extends AbstractAction {
	public static final int OFFSET_X = 50;
	public static final int DURATION = 30;
	
	public EaseIntoPlay() {
		super();
	}
	
	/**
     * Computes the position of the TextObject using Robert Penner's easing equations.
     *
     * <p>Result is complete if the TextObject has reached its target.</p>
     */
    public ActionResult behave(TextObject to) {
    	BooleanProperty easeSwitchProp;
    	if ((easeSwitchProp = (BooleanProperty)to.getProperty("EaseSwitch")) == null) {
    		// set up the animation
    		setAnim(to);
    		return new ActionResult(false, true, false);
    	}
        if (easeSwitchProp.get()) {
        	return getNextFrame(to, easeSwitchProp);
        } else {
        	// there is nothing to do
        	return new ActionResult(false, true, false);
        }
    }

    /**
     * Sets up a new animation.
     */
    private void setAnim(TextObject to) {
       	if (to.getProperty("EaseSwitch") == null) {
       		// the properties have not been initialized yet, create them
       		to.init("EaseCurrTime", new NumberProperty(0));
       		to.init("EaseStart", new Vector3Property(to.getPosition().get()));
       		to.init("EaseOffset", new Vector3Property(new Vector3(OFFSET_X, 0)));
       		to.init("EaseDuration", new NumberProperty(DURATION));
       		to.init("EaseSwitch", new BooleanProperty(true));
       	} else {
       		// the properties already exist, modify them
       		((NumberProperty)to.getProperty("EaseCurrTime")).set(0);
       		((Vector3Property)to.getProperty("EaseStart")).set(to.getPosition().get());
       		((Vector3Property)to.getProperty("EaseOffset")).set(new Vector3(OFFSET_X, 0));
       		((NumberProperty)to.getProperty("EaseDuration")).set(DURATION);
       		((BooleanProperty)to.getProperty("EaseSwitch")).set(true);
       	}
    }
    
    /**
     * Calculates the next frame.
     */
    private ActionResult getNextFrame(TextObject to, BooleanProperty easeSwitch) {
    	// get all the data
    	float currTime = (float)((NumberProperty)to.getProperty("EaseCurrTime")).get();
   		Vector3 start = ((Vector3Property)to.getProperty("EaseStart")).get();
   		Vector3 offset = ((Vector3Property)to.getProperty("EaseOffset")).get();
   		float duration = (float)((NumberProperty)to.getProperty("EaseDuration")).get();
   		
   		// calculate and set the new positions
   		float newX = Expo.easeOut(currTime, (float)start.x, (float)offset.x, duration);
   		float newY = Expo.easeOut(currTime, (float)start.y, (float)offset.y, duration);
   		to.getPosition().set(new Vector3(newX, newY));
   		
   		if (currTime < duration) {
   			// set up the next iteration
       		currTime++;
   			((NumberProperty)to.getProperty("EaseCurrTime")).set(currTime);
   			return new ActionResult(false, true, false);
   		} else {
   			// the animation is complete
   			easeSwitch.set(false);
   			return new ActionResult(true, true, false);
   		}
    }
}
